home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Online / NNTPd / server / timer.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-12-03  |  4.4 KB  |  208 lines

  1. /*
  2.  * Machinery to run routines off timers.
  3.  */
  4. #include "common.h"
  5.  
  6. #ifdef TIMERS
  7. #ifndef lint
  8. static char rcsid[] =
  9.     "@(#) $Id: timer.c,v 1.9 1994/12/03 21:54:30 sob Exp sob $ (NNTP with TIMERS)";
  10. #endif
  11. #else
  12. #ifndef lint
  13. static char rcsid[] =
  14.     "@(#) $Id: timer.c,v 1.9 1994/12/03 21:54:30 sob Exp sob $ (NNTP without TIMERS)";
  15. #endif
  16. #endif
  17.  
  18. #ifdef TIMERS
  19. #include <sys/time.h>
  20. #include "timer.h"
  21. #if !defined(USG) || defined(SVR4)
  22. #ifndef FD_SETSIZE
  23. /* Forward compatability */
  24. #define FD_SET(n, p)    ((p)->fds_bits[0] |= (1<<(n)))
  25. #define FD_CLR(n, p)    ((p)->fds_bits[0] &= ~(1<<(n)))
  26. #define FD_ISSET(n, p)  ((p)->fds_bits[0] & (1<<(n)))
  27. #define FD_ZERO(p)      ((p)->fds_bits[0] = 0)
  28. #endif
  29. #endif
  30. /* non-portable */
  31. #ifndef BSD_44
  32. #define BUFFERED_DATA(f) ((f)->_cnt > 0)
  33. #endif
  34.  
  35. #ifdef SVR4
  36. #include    <signal.h>
  37. #endif
  38.  
  39. static long lastsecs;
  40.  
  41. /*
  42.  * Should be called before first call to timer_sleep()
  43.  */
  44. void
  45. timer_init(timers, ntimer)
  46.     register struct timer *timers;
  47.     register int ntimer;
  48. {
  49.     register int i;
  50.     register struct timer *tp;
  51.  
  52. #ifdef SYSLOG
  53.     if (ntimer <= 0)
  54.         syslog(LOG_ERR,
  55.             "timer_init(): configuration error, %d timers\n", ntimer);
  56. #endif
  57.  
  58.     /* Reset all timers */
  59.     for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  60.         tp->left = tp->seconds;
  61.  
  62.     /* Start clock */
  63.     lastsecs = time((long *)0);
  64. }
  65.  
  66. /*
  67.  * Sleep until input or next timer needs to be run and then run any
  68.  * expired timers. Returns true if input is available to be read.
  69.  */
  70. int
  71. timer_sleep(timers, ntimer)
  72.     register struct timer *timers;
  73.     register int ntimer;
  74. {
  75. #ifdef    SVR4
  76.     SIGRET nullfunc();
  77. #endif
  78.     register int i, n;
  79.     register struct timer *tp;
  80.     register long secs;
  81. #if defined(USG) && !defined(SVR4) && !defined(hpux)
  82.     long timeout;
  83.     long readfds;
  84. #else
  85.     register struct timeval *timeoutp;
  86.     struct timeval timeout;
  87.     fd_set readfds;
  88. #endif
  89.  
  90. #ifdef BUFFERED_DATA
  91.     /* No need to do the select if there are characters in the buffer */
  92.     if (BUFFERED_DATA(stdin))
  93.         return(1);
  94. #endif
  95.  
  96.     /* Length of next timeout is minimum of all "timers" */
  97. #if defined(USG) && !defined(SVR4) && !defined(hpux)
  98.     timeout = -1;
  99.     for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  100.         if (tp->left >= 0 &&
  101.             (tp->left < timeout || timeout < 0))
  102.             timeout = tp->left;
  103.  
  104.     /* If active timeouts (this can easily happen), block until input */
  105.     if (timeout < 0)
  106.         timeout = 0;
  107. #ifdef EXCELAN
  108.     readfds = 1<<(fileno(stdin));
  109.     timeout = timeout * 1000;     /* timeout needs to be in milliseconds */
  110. #endif /* EXCELAN */
  111. #else
  112.     timeout.tv_sec = -1;
  113.     timeout.tv_usec = 0;
  114.     for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  115.         if (tp->left >= 0 &&
  116.             (tp->left < timeout.tv_sec || timeout.tv_sec < 0))
  117.             timeout.tv_sec = tp->left;
  118.  
  119.     /* If active timeouts (this can easily happen), block until input */
  120.     if (timeout.tv_sec <= 0)
  121.         timeoutp = 0;
  122.     else {
  123. #ifdef SVR4
  124.         signal(SIGALRM, nullfunc);
  125.         alarm(timeout.tv_sec);
  126.         timeoutp = 0;
  127. #else
  128.         timeoutp = &timeout;
  129. #endif
  130.     }
  131.  
  132.     /* Do select */
  133.     FD_ZERO(&readfds);
  134.     FD_SET(fileno(stdin), &readfds);
  135. #endif /* !USG */
  136.     errno = 0;
  137. #ifdef EXCELAN
  138.     n = select(fileno(stdin) + 1, &readfds, (long*)0, timeout);
  139. #else
  140.     n = select(fileno(stdin) + 1,
  141.         &readfds, (fd_set*)0, (fd_set*)0, timeoutp);
  142. #endif
  143.     /* "Interrupted system call" isn't a real error */
  144. #ifdef SVR4
  145.     i = errno;
  146.     if (timeout.tv_sec > 0) {
  147.         alarm(0);
  148.         signal(SIGALRM, SIG_IGN);
  149.     }
  150.     errno = i;
  151. #endif
  152.     if (n < 0 && errno != EINTR) {
  153. #ifdef SYSLOG
  154.         syslog(LOG_ERR, "%s read select: %m", hostname);
  155. #endif
  156.         exit(1);
  157.     }
  158.  
  159.     /* Calculate off seconds since last time */
  160.     secs = time((long *)0) - lastsecs;
  161.     if (secs < 0)
  162.         secs = 0;
  163.  
  164.     /* Subtract time from "timers" that have time remaining */
  165.     for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  166.         if (tp->left > 0 && (tp->left -= secs) < 0)
  167.             tp->left = 0;
  168.  
  169.     /* Update lastsecs */
  170.     lastsecs += secs;
  171.  
  172.     /* If we have input, reset clock on guys that like it that way */
  173.     if (n > 0)
  174.         for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  175.             if (tp->resetoninput)
  176.                 tp->left = tp->seconds;
  177.  
  178.     /* Process "timers" that have timed out */
  179.     for (i = ntimer, tp = timers; i > 0; --i, ++tp) {
  180.         if (tp->left == 0) {
  181.             (tp->subr)();
  182.             /* resetoninput guys only get "reset on input" */
  183.             if (tp->resetoninput)
  184.                 tp->left = -1;
  185.             else
  186.                 tp->left = tp->seconds;
  187.         }
  188.     }
  189.  
  190.     /* Indicate no input */
  191.     if (n <= 0)
  192.         return(0);
  193.     return(1);
  194.     
  195. }
  196.  
  197. #ifdef SVR4
  198. SIGRET
  199. nullfunc()
  200. {
  201.     signal(SIGALRM, nullfunc);
  202. #ifndef VOIDSIG
  203.     return 0;
  204. #endif
  205. }
  206. #endif /* SVR4 */
  207. #endif /* TIMERS */
  208.